//----------------------------------------------------------------------------------------
// @Project Includes
#include "includes.h"

//----------------------------------------------------------------------------------------
// @Local Macro Define in the module

//----------------------------------------------------------------------------------------
// @Local Type defines in the module

//----------------------------------------------------------------------------------------
// @Global Variables define in the module
stc_j1939_t g_stcJ1939 = {0};

//----------------------------------------------------------------------------------------

// @Prototypes of functions in the module

//========================================================================================
/*
 * @Functions:   static void srv_j1939_generalResponse(uint8_t result)
 * @Description: 通用应答
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_generalResponse(uint8_t result)
{
		g_stcSrvCan.ungeneralResponse.Bit.u8result = result;
		g_stcSrvCan.ungeneralResponse.Bit.back1 = 0;
    if (g_stccan.vu8canTxMQPushLen < CAN_MAX_TX_SIZE)/*保护，防止溢出*/
    {
        /* Init Transmit frame*/
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].ExtId   = CAN_UPG_RESPOND_ID; 
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].IDE     = CAN_UPG_RESPOND_ID_IDE;  
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].RTR     = CAN_RTRQ_DATA;   
        g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].DLC     = CAN_TX_DLC;  
        memcpy(g_stccan.canTxMessage[g_stccan.vu8canTxMQPushLen].Data ,&g_stcSrvCan.ungeneralResponse.Data[0],8);
        g_stccan.vu8canTxMQPushLen++;
    }
    if (g_stccan.vu8canTxMQPushLen >= CAN_MAX_TX_SIZE)
    {
        g_stccan.vu8canTxMQPushLen = 0;
    }			
		
}

/*
 * @Functions:   void srv_j1939_fwInfoCallback(void)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_fwInfoCallback(void)
{
    uint8_t writeBuf[UPDATE_TAG_SIZE] = {0};
    uint8_t readBuf[UPDATE_TAG_SIZE] = {0};
    uint16_t i = 0;			
		
		writeBuf[0] = 0x5A;
		writeBuf[1] = 0xA5;
		
		writeBuf[2] = 0x78;/*表明CAN升级标志*/
		writeBuf[3] = g_stcSrvCan.unfirmwareInfo.Bit.u16ver >> 0;
		writeBuf[4] = g_stcSrvCan.unfirmwareInfo.Bit.u16ver >> 8;
		writeBuf[5] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 0;
		writeBuf[6] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 8;		
		writeBuf[7] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 16;
		writeBuf[8] = g_stcSrvCan.unfirmwareInfo.Bit.u32size >> 24;		
		writeBuf[9] = g_stcSrvCan.unfirmwareInfo.Bit.u16crc >> 0;/*根据协议特殊处理*/
		writeBuf[10] = g_stcSrvCan.unfirmwareInfo.Bit.u16crc >> 8;			
			
		drv_flash_write(writeBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
		drv_flash_read(readBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
		for (i = 0; i < UPDATE_TAG_SIZE; i++)
		{
				if (writeBuf[i] != readBuf[i])
				{
						printf("Modbus:<< OTA write update data error!g_stcVar.m_stcUpgInfo[%d]=0x%0x tempBuf[%d]=0x%0x\r\n", i, writeBuf[i], i, readBuf[i]);
						memset((void *) writeBuf, 0x00, 11);
						drv_flash_write(writeBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
						srv_j1939_generalResponse(1);
						return ; 
				}
		}
		srv_j1939_generalResponse(0);
		gstcOtaUpdataInfo.u16fwCrc16 = 0; /* tuxin todo */

//		printf("Modbus:<< goto boot upgrade, restart and enter BOOT....\r\n ");
//		drv_systick_delay_ms(2);
//		NVIC_SystemReset();		
		
}

/*
 * @Functions:   void srv_j1939_fwDataCallback(void)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
void srv_j1939_fwDataCallback(void)
{
		uint8_t i = 0;
		uint8_t Temp[J1939_MAX_DATA_SIZE + 20] = {0};	
	
		if (g_stcSrvCan.unfirmwareData.Bit.u8packNumber == 0x00)/*升级包内容信息*/
		{
				g_stcJ1939.u32baseAddress = (((uint32_t)g_stcSrvCan.unfirmwareData.Data[1] << 24)| 
																		((uint32_t)g_stcSrvCan.unfirmwareData.Data[2] << 16)| 
																		((uint32_t)g_stcSrvCan.unfirmwareData.Data[3] << 8)| 
																		((uint32_t)g_stcSrvCan.unfirmwareData.Data[4] << 0)  
																		);	
				g_stcJ1939.u16packLen = 		(((uint16_t)g_stcSrvCan.unfirmwareData.Data[5] << 8)| 
																		((uint16_t)g_stcSrvCan.unfirmwareData.Data[6] << 0) 
																		);
        if ((g_stcJ1939.u16packLen % 7) != 0)
				{
						g_stcJ1939.u8packNum = g_stcJ1939.u16packLen / 7 + 1;
				}	
        else
				{
						g_stcJ1939.u8packNum = g_stcJ1939.u16packLen / 7;
				}	
        for (i = 0; i < g_stcJ1939.u8packNum; i++)
				{
						g_stcJ1939.bflag[i] = true;
				}
				memset(&g_stcJ1939.u8Temp,0x00,J1939_MAX_DATA_SIZE);	
		}
		else
		{
				if (g_stcSrvCan.unfirmwareData.Bit.u8packNumber == g_stcJ1939.u8packNum)/*最后一包*/
				{
					  g_stcJ1939.bflag[g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1] = false;
						memcpy(&g_stcJ1939.u8Temp[(g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1)*7],&g_stcSrvCan.unfirmwareData.Data[1],(g_stcJ1939.u16packLen - (g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1)*7)); 					
					  
					  drv_flash_write(&g_stcJ1939.u8Temp[0], DEVICE_MAIN_APP_ADDR + g_stcJ1939.u32baseAddress, g_stcJ1939.u16packLen);
            drv_flash_read(Temp, DEVICE_MAIN_APP_ADDR + g_stcJ1939.u32baseAddress, g_stcJ1939.u16packLen);
            gstcOtaUpdataInfo.u16fwCrc16 = srv_crc16_system(Temp,g_stcJ1939.u16packLen,gstcOtaUpdataInfo.u16fwCrc16);/* tuxin todo */
						printf("crc gstcOtaUpdataInfo.u16fwCrc16 = 0x%x \r\n",gstcOtaUpdataInfo.u16fwCrc16);
					  for (i = 0; i < g_stcJ1939.u8packNum; i++)
						{
								if (g_stcJ1939.bflag[i] != false)
								{
										srv_j1939_generalResponse(1);
									  return;
								}
						}
						srv_j1939_generalResponse(0);
						
				}
				else
				{
					  g_stcJ1939.bflag[g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1] = false;
						memcpy(&g_stcJ1939.u8Temp[(g_stcSrvCan.unfirmwareData.Bit.u8packNumber - 1)*7],&g_stcSrvCan.unfirmwareData.Data[1],7); 
				}
		}
}

/*
 * @Functions:   bool_t srv_j1939_fwResultCallback(void)
 * @Description: can回调
 * @Parameters:  NONE
 * @Return:      NONE
 */
bool_t srv_j1939_fwResultCallback(void)
{
    uint8_t writeBuf[UPDATE_TAG_SIZE] = {0};
    //uint8_t readBuf[UPDATE_TAG_SIZE] = {0};
		
		#define MAGIC_ADDR_BASE   (0x8005000)
		#define MAGIC_REVISION   ("CBMS-xxx-0328800387")
		uint8_t cRevision_Magic[40] = {0};
			
		drv_flash_read(cRevision_Magic, MAGIC_ADDR_BASE, sizeof(MAGIC_REVISION));	

		if (strcmp((char*)cRevision_Magic, MAGIC_REVISION) == 0)
		{   
				printf("magic check ok!\r\n");
		}
		else
		{
				srv_j1939_generalResponse(1);
				printf("magic check error!\r\n");
				return false;
		}
				
		if(gstcOtaUpdataInfo.u16fwCrc16  != gstcOtaUpdata.u16fwCrc16)
		{
				srv_j1939_generalResponse(1);
				printf("crc check error! gstcOtaUpdataInfo.u16fwCrc16 = 0x%x gstcOtaUpdataInfo.u16fwCrc16 = 0x%x \r\n",
			                           gstcOtaUpdataInfo.u16fwCrc16,gstcOtaUpdata.u16fwCrc16);
				return false;
		}
		else
		{
				srv_j1939_generalResponse(0);
			
				memset((void *) writeBuf, 0x00, 11);
				drv_flash_write(writeBuf, OTA_CONFIG_ADDR, UPDATE_TAG_SIZE);
				printf("Modbus:<< The upgrade is complete, restart and enter BOOT....\r\n ");
				return true;						
		}

}

// =======================================================================================
// End of file.
// =======================================================================================
